home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / tuwtcpsr / tuwtcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  13.4 KB  |  687 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <tos.h>
  5.  
  6. #include "nettrace.h"
  7. static char str[200];
  8. void (*nettrace)(register char *);
  9.  
  10. #define noDEBUGSTAT
  11. #define noDEBUGAPP
  12. #define noDEBUG
  13.  
  14. #define VERSION "1.31"
  15.  
  16. #define VBLCNT 0x454L
  17. #define VBLLIST 0x456L
  18.  
  19. /*        UPDATELIST                                                    */
  20. /*  27. 4.92    hw        fixed malloc problem (basepage switching)    */
  21. /*  27. 9.92    pm        fixed double SYN ACK reset                    */
  22. /*  15.10.92    pm        fixed double ACK, window management         */
  23. /*  23.10.92    pm        fixed FIN, SYNREC, ack policy ...              */
  24. /*  30.10.92    pm        added URGENT                                  */
  25. /*  18. 2.93    pm        fixed abort problem if no packet free        */
  26. /*              pm      fixed freeing of packets                    */
  27.  
  28. #include "pktdrv.h"
  29. #include "ip.h"
  30. #include "arp.h"
  31. #include "icmp.h"
  32. #include "tcp.h"
  33. #include "udp.h"
  34. #include "netdb.h"
  35. #include "cookie.h"
  36. #include "inetcust.h"
  37. #include "tuwtcp.h"
  38. #include "gemhook.h"
  39. #include "mbuf.h"
  40.  
  41. extern int net_link(void);
  42.  
  43. long linkin(void);
  44. void (*myprog)();
  45. long * vbl_hook;
  46.  
  47. #define MACHINECOOKIE    0x5f4d4348L        /* "_MCH" */
  48. #define TRAP_1             33                /* GEMDOS TRAP */
  49. #define TRAP_5             37                /* GEMDOS TRAP */
  50. typedef long (*GEMDOSFUNC)(register char *);
  51.  
  52. #define TCPBASE (1)
  53. #define UDPBASE (100)
  54.  
  55. char myid[] = {"@(#) TUW-TCP v"
  56.                 VERSION };
  57.  
  58. long GETIPADDR(register char *param);
  59. long UDPOPEN(register char *param);
  60. long UDPCLOSE(register char *param);
  61. long UDPREAD(register char *param);
  62. long UDPWRITE(register char *param);
  63. long TCPOPEN(register char *param);
  64. long TCPWRITE(register char *param);
  65. long TCPREAD(register char *param);
  66. long TCPCLOSE(register char *param);
  67. long TCPABORT(register char *param);
  68. long TCPSTATE(register char *param);
  69.  
  70. int tcp_upcall(int tcb,char *data,int len);
  71. int udp_upcall(int tcb,char *data,int len);
  72.  
  73.  
  74. INETCUST *custom = NULL;
  75. char *tcp_buffers;
  76. char *udp_buffers;
  77.  
  78. extern TCP_TCB *tcpcb_list;
  79. extern UDP_CTL *udp_list;
  80. extern PKTQUEUE    *ip_qrecv;
  81. extern long arp_counts[];
  82. extern long icmp_counts[];
  83. extern long udp_counts[];
  84. extern long tcp_counts[];
  85.  
  86. COOKIE *cookie;
  87.  
  88. INETSTAT inetstat;
  89.  
  90. int mode = 0;
  91.  
  92. #define STATMODE 7
  93. #define MUXMODE 4
  94.  
  95. char linebuf[MAXNAME+16];
  96.  
  97.  
  98. GEMDOSFUNC GEM_TAB[] = 
  99. {                    /* gemdos # */
  100.     GETIPADDR,            /* 612 */
  101.     UDPOPEN,            /* 620 */
  102.     UDPCLOSE,            /* 621 */
  103.     UDPREAD,            /* 622 */
  104.     UDPWRITE,            /* 623 */
  105.     TCPOPEN,            /* 630 */
  106.     TCPWRITE,            /* 631 */
  107.     TCPREAD,            /* 632 */
  108.     TCPCLOSE,            /* 633 */
  109.     TCPABORT,            /* 634 */
  110.     TCPSTATE            /* 635 */
  111. };
  112.  
  113.  
  114. typedef struct 
  115. {
  116.     char *_Host;
  117.     unsigned char *_IPAddr;
  118. }getip;
  119.  
  120. #define Host   (((getip *)param)->_Host)
  121. #define IPAddr (((getip *)param)->_IPAddr)
  122.  
  123. long GETIPADDR(register char *param)
  124. {
  125. register FILE *fp;
  126. register char *p_ip;
  127. register char *p_name;
  128. register INADDR inaddr;
  129.  
  130.     if(!custom) return(-1);
  131.     if(!Host)
  132.     {            /* return own IP-Address */
  133.         *(INADDR *)IPAddr = custom->inaddr;
  134.         return(0);
  135.     }
  136.     fp = fopen(custom->hosts,"r");
  137.     if(!fp) return(-1);
  138.     while(fgets(linebuf,(int)sizeof(linebuf)-1,fp) != NULL)
  139.     {
  140.         if(linebuf[0] == '#') continue;
  141.         p_ip = strtok(linebuf," \t");
  142.         if(!p_ip) continue;
  143.         inaddr = atoin(p_ip);
  144.         if(!inaddr) continue;
  145.         while((p_name = strtok(NULL," \t\n")) != NULL)
  146.         {
  147.             if(!Host[0])
  148.             {
  149.                 if(inaddr == *(INADDR *)IPAddr)
  150.                 {
  151.                     strcpy(Host,p_name);
  152.                     fclose(fp);
  153.                     return(0);
  154.                 }
  155.             }
  156.             if(!strcmp(Host,p_name))
  157.             {
  158.                 *(INADDR *)IPAddr = inaddr;
  159.                 fclose(fp);
  160.                 return(0);
  161.             }
  162.         }
  163.     }
  164.     fclose(fp);
  165.     return(-1);
  166. }
  167. #undef Host
  168. #undef IPAddr
  169.  
  170.  
  171. typedef struct
  172. {
  173.     unsigned int    _port;
  174. } udpo;
  175.  
  176. #define port    (((udpo *)param)->_port)
  177.  
  178. long UDPOPEN(register char *param)
  179. {
  180. register int ret;
  181.     net_demux(FALSE,DEMUX);
  182.     ret = udp_open(port,udp_upcall);
  183.     if(ret < 0) return(ret);
  184.     return((long)ret + UDPBASE);
  185. }
  186. #undef port
  187.  
  188.  
  189.  
  190. typedef struct
  191. {
  192.     unsigned int    _UDPID;
  193. } udpc;
  194.  
  195. #define UDPID    (((udpc *)param)->_UDPID)
  196.  
  197. long UDPCLOSE(register char *param)
  198. {
  199. register int ret;
  200.     ret = udp_close(UDPID-UDPBASE);
  201.     net_demux(FALSE,DEMUX);
  202.     if(ret < 0) return(ret);
  203.     return(UDPID);
  204. }
  205. #undef UDPID
  206.  
  207.  
  208.  
  209. typedef struct
  210. {
  211.     unsigned int    _UDPID;
  212.     char             *_Buffer;
  213.     DESTI            *_src;
  214. } udpr;
  215.  
  216. #define UDPID    (((udpr *)param)->_UDPID)
  217. #define Buffer    (((udpr *)param)->_Buffer)
  218. #define src        (((udpr *)param)->_src)
  219.  
  220. long UDPREAD(register char *param)
  221. {
  222. long len;
  223. UDP_CTL *p_udpctl;
  224.  
  225.     net_demux(FALSE,DEMUX);
  226.     p_udpctl = udp_getctl(UDPID-UDPBASE);
  227.     if(!p_udpctl) return(-1);
  228.     if(p_udpctl->udp_err == UDP_NORECV) return(-1);
  229.     if(!p_udpctl->data_len || !p_udpctl->data) return(0);
  230.     len = (long)p_udpctl->data_len;
  231.     memcpy(Buffer,p_udpctl->data,len);
  232.     *(long *)src->IPAddr = p_udpctl->fhost;
  233.     src->Port = p_udpctl->fgn_port;
  234.     udp_free(UDPID-UDPBASE);
  235.     return(len);
  236. }
  237. #undef UDPID
  238. #undef Buffer
  239. #undef src
  240.  
  241.  
  242.  
  243. typedef struct
  244. {
  245.     unsigned int    _UDPID;
  246.     char             *_Buffer;
  247.     unsigned int    _len;
  248.     DESTI            *_dest;
  249. } udpw;
  250.  
  251. #define UDPID    (((udpw *)param)->_UDPID)
  252. #define Buffer    (((udpw *)param)->_Buffer)
  253. #define len        (((udpw *)param)->_len)
  254. #define dest    (((udpw *)param)->_dest)
  255.  
  256. long UDPWRITE(register char *param)
  257. {
  258. register int ret;
  259.  
  260.     ret = udp_write(UDPID-UDPBASE,Buffer,len,*(long *)(dest->IPAddr),dest->Port);
  261.     net_demux(FALSE,DEMUX);
  262.     return((long)ret);
  263. }
  264. #undef UDPID
  265. #undef Buffer
  266. #undef len
  267. #undef dest
  268.  
  269.  
  270.  
  271. typedef struct
  272. {
  273.     unsigned int    _port;
  274.     DESTI           *_dest;
  275.     unsigned int     _APflag;
  276.     unsigned int    _timeout;
  277.     unsigned long    _rwin;
  278. } tcpo;
  279.  
  280. #define port    (((tcpo *)param)->_port)
  281. #define dest    (((tcpo *)param)->_dest)
  282. #define APFlag    (((tcpo *)param)->_APflag)
  283. #define timeout    (((tcpo *)param)->_timeout)
  284. #define rwin    (((tcpo *)param)->_rwin)
  285.  
  286. long TCPOPEN(register char *param)
  287. {
  288. int tcp;
  289. #ifdef DEBUG
  290. TRACE("TCPOPEN\n");
  291. #endif
  292.  
  293.     if(APFlag != AKTIV && APFlag != PASSIV) return(0);
  294.     if(rwin > 65535L) return(0);    /* receivewindow is unsigned short */
  295.     tcp = tcp_create(rwin,rwin,tcp_upcall);
  296.     if(tcp < 0) return(0);
  297.     if(port) tcp_bind(tcp,port);
  298.         
  299.     if(APFlag == AKTIV)
  300.     {
  301.         if(tcp_open(tcp,*(INADDR *)dest->IPAddr,dest->Port,tm_msec(timeout)) < 0)
  302.         {
  303.             tcp_delete(tcp);
  304.             return(0);
  305.         }
  306.     }
  307.     else
  308.     {
  309.         if(tcp_listen(tcp,port,tm_msec(timeout))<0)
  310.         {
  311.             tcp_delete(tcp);
  312.             return(0);
  313.         }
  314.     }
  315.     net_demux(FALSE,DEMUX);        /* process incoming packets */
  316.     return((long)tcp+TCPBASE);    /* return tcp id > 0 */
  317. }
  318. #undef port
  319. #undef dest
  320. #undef APFlag
  321. #undef timeout
  322. #undef rwin
  323.  
  324.  
  325.  
  326. typedef struct
  327. {
  328.     unsigned int    _TCPID;
  329.     char *            _Buffer;
  330.     unsigned int     _len;
  331.     unsigned int    _Pflg;
  332.     unsigned int    _Uflg;
  333. } tcpwr;
  334.  
  335. #define TCPID    (((tcpwr *)param)->_TCPID)
  336. #define Buffer    (((tcpwr *)param)->_Buffer)
  337. #define len        (((tcpwr *)param)->_len)
  338. #define Pflg    (((tcpwr *)param)->_Pflg)
  339. #define Uflg    (((tcpwr *)param)->_Uflg)
  340.  
  341. long TCPWRITE(register char *param)
  342. {
  343. long sent;
  344.  
  345.     /*if(Uflg == URGENT) return(-1);*/
  346.     TCPID -= TCPBASE;
  347.     sent = tcp_write(TCPID,Buffer,len,(Pflg == PUSH ? TCP_PUSH : 0) | (Uflg == URGENT ? TCP_URG : 0));
  348.     net_demux(FALSE,DEMUX);
  349.     return(sent);
  350. }
  351.  
  352. #undef TCPID
  353. #undef Buffer
  354. #undef len
  355. #undef Pflg
  356. #undef Uflg
  357.  
  358.  
  359. typedef struct
  360. {
  361.     unsigned int    _TCPID;
  362.     char *            _Buffer;
  363.     unsigned int     _len;
  364. } tcprd;
  365.  
  366. #define TCPID    (((tcprd *)param)->_TCPID)
  367. #define Buffer    (((tcprd *)param)->_Buffer)
  368. #define len        (((tcprd *)param)->_len)
  369.  
  370. long TCPREAD(register char *param)
  371. {
  372. register long got;
  373. #ifdef VDEBUG
  374. TRACE(">TCP_READ, demux\n");
  375. #endif
  376.     net_demux(FALSE,DEMUX);
  377. #ifdef DEBUG
  378. TRACE(">>TCP_READ, tcp_read\n");
  379. #endif
  380.     got = (long)tcp_read(TCPID-TCPBASE,Buffer,len);
  381. #ifdef DEBUG
  382. TRACE("<TCP_READ\n");
  383. #endif
  384.     return(got);
  385. }
  386.  
  387. #undef TCPID
  388. #undef Buffer
  389. #undef len
  390.  
  391.  
  392. typedef struct
  393. {
  394.     unsigned int    _TCPID;
  395. } tcpc;
  396.  
  397. #define TCPID    (((tcpc *)param)->_TCPID)
  398.  
  399. long TCPCLOSE(register char *param)
  400. {
  401. int tcp;
  402.     tcp = tcp_close(TCPID - TCPBASE);
  403.     net_demux(FALSE,DEMUX);
  404.     return(tcp<0 ? -1L : TCPID);
  405. }
  406.  
  407. #undef TCPID
  408.  
  409. typedef struct
  410. {
  411.     unsigned int    _TCPID;
  412. } tcpa;
  413. #define TCPID    (((tcpa *)param)->_TCPID)
  414.  
  415. long TCPABORT(register char *param)
  416. {
  417. int tcp;
  418.     tcp = tcp_abort(TCPID - TCPBASE);
  419.     return(tcp<0 ? -1L : (long)TCPID);
  420. }
  421.  
  422. #undef TCPID
  423.  
  424. typedef struct
  425. {
  426.     unsigned int    _TCPID;
  427.     TCPSTAT        *_statblk;
  428. } tcps;
  429. #define TCPID    (((tcps *)param)->_TCPID)
  430. #define statblk    (((tcps *)param)->_statblk)
  431.  
  432. long TCPSTATE(register char *param)
  433. {
  434. TCP_TCB *tcb;
  435.  
  436. #ifdef DEBUGSTAT
  437. sprintf(str,">tcp_stat tcpid %u\n",TCPID);
  438. TRACE(str);
  439.  
  440. TRACE(">>tcpstat ... do demux\n");    
  441. #endif
  442.     mode = MUXMODE;
  443.     net_demux(FALSE,DEMUX);
  444.     mode = STATMODE;
  445. #ifdef DEBUGSTAT
  446. TRACE("<<tcpstat ... back from demux\n");    
  447. #endif
  448.     if(!TCPID || !statblk)
  449.     {
  450. #ifdef DEBUGSTAT
  451. TRACE("<tcp_stat - no TCPID or statblock\n");
  452. #endif
  453.      return(-1L);
  454.     }
  455.     tcb = tcp_gettcb(TCPID - TCPBASE);
  456.     if(!tcb)
  457.     {
  458. #ifdef DEBUGSTAT
  459. TRACE("<tcp_stat - no such tcb\n");
  460. #endif
  461.      return(-1L);
  462.     }
  463.     statblk->TCP_ID = TCPID;
  464.     statblk->TCP_Port = tcb->lcl_port;
  465.     statblk->TCP_Dest.Port = tcb->fgn_port;
  466.     *(INADDR *)(statblk->TCP_Dest.IPAddr) = tcb->fhost;
  467.     statblk->TCP_State = tcb->state;
  468.     statblk->TCP_Urgent = 0;
  469.     statblk->TCP_Timeout = (int)(tcb->timeout / 200);
  470.     statblk->TCP_RWin = tcb->q_in.size;
  471.     statblk->TCP_RWfree = q_free(&(tcb->q_in));
  472. #ifdef DEBUGSTAT
  473. sprintf(str,"<tcp_stat ok, l_%u.f_%u %d\n",tcb->lcl_port,tcb->fgn_port,tcb->state);
  474. TRACE(str);
  475. #endif
  476.     return((long)tcb->state);
  477. }
  478.  
  479. #undef TCPID
  480. #undef statblk
  481.  
  482. long tuwinit(void)
  483. {
  484.     cookie = get_cookie(INETCUSTCOOKIE);
  485.     if(!cookie)
  486.     {
  487.         fprintf(stderr," - INETCUST not loaded\n");
  488.         exit(1);
  489.     }
  490.     custom = (INETCUST *)(cookie->val);
  491.     if(!custom || custom->magic != sizeof(INETCUST))
  492.     {
  493.         fprintf(stderr," - invalid custom structure found(%ld->%ld\n",custom->magic,sizeof(INETCUST));
  494.         exit(1);
  495.     }
  496.  
  497.     if(net_link() < 0)
  498.     {
  499.         fprintf(stderr," - packet driver not found\n");
  500.         exit(1);
  501.     }
  502.  
  503.     tcp_buffers = buf_create(custom->netmem);
  504.     if(!tcp_buffers)
  505.     {
  506.         fprintf(stderr," - out of memory to allocate buffers\n");
  507.         exit(1);
  508.     }
  509.     
  510.     udp_buffers = buf_create(UDP_MAXPORTS * sizeof(UDP_CTL));
  511.  
  512.     if(!udp_buffers)
  513.     {
  514.         fprintf(stderr," - out of memory to allocate buffers\n");
  515.         Mfree(tcp_buffers);
  516.         exit(1);
  517.     }
  518.     
  519.     if(!ip_init())            /* init services */
  520.     {
  521.         fprintf(stderr," - cannot init IP layer\n");
  522.         Mfree(tcp_buffers);
  523.         Mfree(udp_buffers);
  524.         exit(1);
  525.     }
  526.     if(!tcp_init())
  527.     {
  528.         ip_exit();
  529.         fprintf(stderr," - cannot init TCP layer\n");
  530.         Mfree(tcp_buffers);
  531.         Mfree(udp_buffers);
  532.         exit(1);
  533.     }
  534.     if(!udp_init())
  535.     {
  536.         ip_exit();
  537.         fprintf(stderr," - cannot init UDP layer\n");
  538.         Mfree(tcp_buffers);
  539.         Mfree(udp_buffers);
  540.         exit(1);
  541.     }
  542.     
  543.  inetstat.tcpcb_list = &tcpcb_list;
  544.  inetstat.udp_list = &udp_list;
  545.  inetstat.ip_qrecv = &ip_qrecv;
  546.  inetstat.arp_counts = arp_counts;
  547.  inetstat.icmp_counts = icmp_counts;
  548.  inetstat.udp_counts = udp_counts;
  549.  inetstat.tcp_counts = tcp_counts;
  550.  
  551.     add_cookie(INETCOOKIE,(long)(&inetstat));
  552.     cookie = get_cookie(MACHINECOOKIE);
  553.  
  554.     if(!cookie || (cookie->val >> 16) != 2)
  555.         OLD_GEMDOS = Setexc(TRAP_1,ST_GEMDOS);
  556.     else
  557.         OLD_GEMDOS = Setexc(TRAP_1,TT_GEMDOS);
  558.         Setexc(TRAP_5,TRP5SIM);
  559.  
  560.         myprog = NET_TICK;
  561.  
  562.              printf(" installed\n"
  563.            "%ld bytes resident\n"
  564.            "(c) hw/pm ForTec 1992,93\n\a",
  565.            _PgmSize+custom->netmem+UDP_MAXPORTS * sizeof(UDP_CTL));
  566. /*        if(linkin())
  567.         {
  568.           printf("\n - cannot install net-tick\n");
  569.         }
  570. */        return 0;
  571. }
  572.  
  573. main()
  574. {
  575.  
  576.         printf("\nTUW-TCP v%s",VERSION);
  577.  
  578. #ifdef NETTRACE
  579.     TRACE("TUWTCP startup\n");
  580. #endif
  581.  
  582. Supexec(tuwinit);
  583.  
  584. #ifdef DEBUG    printf("net_demux at %lx",(long)net_demux);
  585.     Cconin();
  586. #endif
  587.  
  588. #ifdef DEBUGAPP
  589. {
  590. DESTI desti;
  591. int tcp_id,x,i;
  592. char data[100];
  593. TCPSTAT tstat;
  594.  
  595. #define tcp_xopen(a,b,c,d,e)        gemdos(630,a,b,c,d,e)
  596. #define tcp_xwrite(a,b,c,d,e)    gemdos(631,a,b,c,(char)d,(char)e)
  597. #define tcp_xread(a,b,c)            gemdos(632,a,b,c)
  598. #define    tcp_xclose(a)            gemdos(633,a)
  599. #define tcp_xstat(a,b)            gemdos(635,a,b)
  600.  
  601.     desti.IPAddr[0] = 128;
  602.     desti.IPAddr[1] = 130;
  603.     desti.IPAddr[2] = 70;
  604.     desti.IPAddr[3] = 130;
  605.     desti.Port = 23;
  606.   
  607.     tcp_id = (unsigned)tcp_xopen(0,&desti,AKTIV,60,4096L);
  608.     while(tcp_xstat(tcp_id,&tstat) != ESTABLISHED);
  609. do
  610. {
  611.     if(Cconis())
  612.     {
  613.     data[0] = Cconin();
  614.     x=(int)tcp_xwrite(tcp_id,&data,1,PUSH,NO_URGENT);
  615.     if(data[0] == 3) break;
  616.     }
  617.     x = (int)tcp_xread(tcp_id,&data,10);
  618.     for(i=0;i<x;Cconout(data[i++]));
  619. }while(1);
  620.     tcp_xclose(tcp_id);
  621.     tcp_exit();
  622.     udp_exit();
  623.     ip_exit();
  624. }
  625. #else
  626.     Ptermres(_PgmSize,0);        /* sit into memory */
  627. #endif
  628.     return(0);
  629. }
  630.  
  631.  
  632. int udp_upcall(int tcb,char *data,int len)
  633. {
  634.     return(0);
  635. }
  636.  
  637. int tcp_upcall(int tcb,char *data,int len)
  638. {
  639.  
  640.         /* upcall codes if datapointer in upcall is NULL */
  641.     if(!data) switch(len)
  642.     {
  643.         case TCP_UCESTAB:
  644.             return(0);
  645.             
  646.         case TCP_UCRESET:
  647.             return(0);
  648.             
  649.         case TCP_UCCLOSING:
  650.             return(0);
  651.             
  652.         case TCP_UCTIMEOUT:
  653.         case TCP_UCDATA:
  654.         case TCP_UCCLOSEWT:
  655.         case TCP_UCCLOSED:
  656.             break;
  657.     }
  658.     return(0);
  659. }
  660. /*
  661. long linkin(void)
  662. {
  663.  int cnt,i;
  664.  void (**queue)();
  665.  extern void (*myprog)();
  666.  extern long *vbl_hook;
  667.  
  668.  vbl_hook = NULL;
  669.  cnt = *(int*)VBLCNT;
  670.  queue = *((void(***)())VBLLIST);
  671.  
  672.  for(i = 1;i < cnt;i++)
  673.  {
  674.    if(queue[i] == 0L)
  675.    {
  676.      *(queue+i) = myprog;
  677.      vbl_hook = (long*)(queue+i);
  678.      break;
  679.    }
  680.  }
  681.  if(i < cnt) return 0;
  682.  else return 1;
  683.  
  684.  OLD_TICK = Setexc(69,myprog);
  685.  return 0;
  686. }
  687. */